home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / jikes-1.11 / src / definite.cpp < prev    next >
C/C++ Source or Header  |  2000-02-23  |  91KB  |  2,342 lines

  1. // $Id: definite.cpp,v 1.14 1999/10/17 01:58:40 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <assert.h>
  12. #include <stdio.h>
  13. #include "semantic.h"
  14.  
  15. DefiniteAssignmentSet *Semantic::DefiniteExpression(AstExpression *expr, BitSet &set)
  16. {
  17.     DefiniteAssignmentSet *definite = NULL;
  18.  
  19.     //
  20.     // Is the expression a constant expression of type boolean?
  21.     // Recall that a constant expression may not contain an
  22.     // assignment statement.
  23.     //
  24.     if (expr -> IsConstant() && expr -> Type() == control.boolean_type)
  25.     {
  26.         definite = new DefiniteAssignmentSet(universe -> Size());
  27.         IntLiteralValue *result = (IntLiteralValue *) expr -> value;
  28.         if (result -> value)
  29.         {
  30.             definite -> true_set  = set;
  31.             definite -> false_set = *universe;
  32.         }
  33.         else
  34.         {
  35.             definite -> true_set  = *universe;
  36.             definite -> false_set = set;
  37.         }
  38.     }
  39.     else if (expr -> symbol != control.no_type)
  40.         definite = (this ->* DefiniteExpr[expr -> kind])(expr, set);
  41.  
  42.     return definite;
  43. }
  44.  
  45.  
  46. DefiniteAssignmentSet *Semantic::DefiniteSimpleName(AstExpression *expression, BitSet &set)
  47. {
  48.     AstSimpleName *simple_name = (AstSimpleName *) expression;
  49.  
  50.     if (simple_name -> resolution_opt)
  51.         return DefiniteExpression(simple_name -> resolution_opt, set);
  52.  
  53.     //
  54.     // Some simple names are undefined. e.g., the simple name in a method call.
  55.     //
  56.     VariableSymbol *variable = (simple_name -> symbol ? simple_name -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  57.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  58.     {
  59.         if (! set[variable -> LocalVariableIndex()])
  60.         {
  61.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  62.                            simple_name -> identifier_token,
  63.                            simple_name -> identifier_token,
  64.                            variable -> Name());
  65.  
  66.             if (variable -> IsLocal(ThisMethod())) // to avoid cascading errors!
  67.                 set.AddElement(variable -> LocalVariableIndex());
  68.         }
  69.     }
  70.  
  71.     return (DefiniteAssignmentSet *) NULL;
  72. }
  73.  
  74.  
  75. DefiniteAssignmentSet *Semantic::DefiniteArrayAccess(AstExpression *expression, BitSet &set)
  76. {
  77.     AstArrayAccess *array_access = (AstArrayAccess *) expression;
  78.  
  79.     DefiniteAssignmentSet *after_base = DefiniteExpression(array_access -> base, set);
  80.     if (after_base) // if this is true then something is wrong
  81.     {
  82.         set = after_base -> true_set * after_base -> false_set;
  83.         delete after_base;
  84.     }
  85.  
  86.     DefiniteAssignmentSet *after_expr = DefiniteExpression(array_access -> expression, set);
  87.     if (after_expr) // if this is true then something is wrong
  88.     {
  89.         set = after_expr -> true_set * after_expr -> false_set;
  90.         delete after_expr;
  91.     }
  92.  
  93.     return (DefiniteAssignmentSet *) NULL;
  94. }
  95.  
  96.  
  97. DefiniteAssignmentSet *Semantic::DefiniteMethodInvocation(AstExpression *expression, BitSet &set)
  98. {
  99.     AstMethodInvocation *method_call = (AstMethodInvocation *) expression;
  100.  
  101.     DefiniteAssignmentSet *after_method = DefiniteExpression(method_call -> method, set);
  102.     if (after_method)
  103.     {
  104.         set = after_method -> true_set * after_method -> false_set;
  105.         delete after_method;
  106.     }
  107.  
  108.     for (int i = 0; i < method_call -> NumArguments(); i++)
  109.     {
  110.         AstExpression *expr = method_call -> Argument(i);
  111.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  112.         if (after_expr)
  113.         {
  114.             set = after_expr -> true_set * after_expr -> false_set;
  115.             delete after_expr;
  116.         }
  117.     }
  118.  
  119.     return (DefiniteAssignmentSet *) NULL;
  120. }
  121.  
  122.  
  123. DefiniteAssignmentSet *Semantic::DefiniteClassInstanceCreationExpression(AstExpression *expression, BitSet &set)
  124. {
  125.     AstClassInstanceCreationExpression *class_creation = (AstClassInstanceCreationExpression *) expression;
  126.  
  127.     if (class_creation -> base_opt)
  128.     {
  129.         DefiniteAssignmentSet *after_expr = DefiniteExpression(class_creation -> base_opt, set);
  130.         if (after_expr)
  131.         {
  132.             set = after_expr -> true_set * after_expr -> false_set;
  133.             delete after_expr;
  134.         }
  135.     }
  136.  
  137.     for (int i = 0; i < class_creation -> NumLocalArguments(); i++)
  138.     {
  139.         AstExpression *expr = class_creation -> LocalArgument(i);
  140.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  141.         if (after_expr)
  142.         {
  143.             set = after_expr -> true_set * after_expr -> false_set;
  144.             delete after_expr;
  145.         }
  146.     }
  147.  
  148.     for (int k = 0; k < class_creation -> NumArguments(); k++)
  149.     {
  150.         AstExpression *expr = class_creation -> Argument(k);
  151.         DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  152.         if (after_expr)
  153.         {
  154.             set = after_expr -> true_set * after_expr -> false_set;
  155.             delete after_expr;
  156.         }
  157.     }
  158.  
  159.     return (DefiniteAssignmentSet *) NULL;
  160. }
  161.  
  162.  
  163. DefiniteAssignmentSet *Semantic::DefiniteArrayCreationExpression(AstExpression *expression, BitSet &set)
  164. {
  165.     AstArrayCreationExpression *array_creation = (AstArrayCreationExpression *) expression;
  166.  
  167.     for (int i = 0; i < array_creation -> NumDimExprs(); i++)
  168.     {
  169.         AstDimExpr *dim_expr = array_creation -> DimExpr(i);
  170.         DefiniteAssignmentSet *after_expr = DefiniteExpression(dim_expr -> expression, set);
  171.         if (after_expr)
  172.         {
  173.             set = after_expr -> true_set * after_expr -> false_set;
  174.             delete after_expr;
  175.         }
  176.     }
  177.  
  178.     if (array_creation -> array_initializer_opt)
  179.         DefiniteArrayInitializer(array_creation -> array_initializer_opt);
  180.  
  181.     return (DefiniteAssignmentSet *) NULL;
  182. }
  183.  
  184.  
  185. inline VariableSymbol *Semantic::DefiniteFinal(AstFieldAccess *field_access)
  186. {
  187.     if (field_access -> resolution_opt)
  188.         field_access = field_access -> resolution_opt -> FieldAccessCast();
  189.  
  190.     if (field_access)
  191.     {
  192.         VariableSymbol *variable = (field_access -> symbol ? field_access -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  193.         if (variable && variable -> IsFinal(ThisType()))
  194.         {
  195.             if (variable -> ACC_STATIC()) // there is exactly one copy of a static variable, so, it's always the right one.
  196.                 return variable;
  197.  
  198.             AstFieldAccess *sub_field_access = field_access -> base -> FieldAccessCast();
  199.             if (field_access -> base -> ThisExpressionCast() || (sub_field_access && sub_field_access -> IsThisAccess()))
  200.                 return variable;
  201.         }
  202.     }
  203.  
  204.     return NULL;
  205. }
  206.  
  207.  
  208. DefiniteAssignmentSet *Semantic::DefinitePLUSPLUSOrMINUSMINUS(AstExpression *expr, BitSet &set)
  209. {
  210.     DefiniteAssignmentSet *definite = DefiniteExpression(expr, set);
  211.     if (definite) // if this is true then something is wrong
  212.     {
  213.         set = definite -> true_set * definite -> false_set;
  214.         delete definite;
  215.     }
  216.  
  217.     VariableSymbol *variable = NULL;
  218.     if (! expr -> ArrayAccessCast()) // some kind of name
  219.     {
  220.         MethodSymbol *read_method = NULL;
  221.         AstSimpleName *simple_name = expr -> SimpleNameCast();
  222.         if (simple_name)
  223.         {
  224.             if (simple_name -> resolution_opt)
  225.                read_method = simple_name -> resolution_opt -> symbol -> MethodCast();
  226.         }
  227.         else
  228.         {
  229.             AstFieldAccess *field_access = expr -> FieldAccessCast();
  230.  
  231.             assert(field_access);
  232.  
  233.             if (field_access -> resolution_opt)
  234.                 read_method = field_access -> resolution_opt -> symbol -> MethodCast();
  235.         }
  236.  
  237.         variable = (read_method ? (VariableSymbol *) read_method -> accessed_member : expr -> symbol -> VariableCast());
  238.     }
  239.  
  240.     //
  241.     // If we have a variable and it is final then...
  242.     //
  243.     if (variable && variable -> ACC_FINAL())
  244.     {
  245.         ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  246.                        expr -> LeftToken(),
  247.                        expr -> RightToken(),
  248.                        variable -> Name());
  249.  
  250.         if (variable -> IsFinal(ThisType())) // if the final variable in contained in this type, then mark it assigned
  251.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  252.     }
  253.  
  254.     return (DefiniteAssignmentSet *) NULL;
  255. }
  256.  
  257.  
  258. DefiniteAssignmentSet *Semantic::DefinitePostUnaryExpression(AstExpression *expression, BitSet &set)
  259. {
  260.     AstPostUnaryExpression *postfix_expression = (AstPostUnaryExpression *) expression;
  261.     return DefinitePLUSPLUSOrMINUSMINUS(postfix_expression -> expression, set);
  262. }
  263.  
  264.  
  265. DefiniteAssignmentSet *Semantic::DefiniteNOT(AstExpression *expr, BitSet &set)
  266. {
  267.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expr, set);
  268.     if (after_expr) // is the expression is a complex boolean expression?
  269.     {
  270.         BitSet temp(after_expr -> true_set);
  271.         after_expr -> true_set = after_expr -> false_set;
  272.         after_expr -> false_set = temp;
  273.     }
  274.  
  275.     return after_expr;
  276. }
  277.  
  278.  
  279. //
  280. // The default pre unary operators are +, -, and ~.
  281. // As these operators are not applicable to boolean expressions,
  282. // we do not need to invoke DefiniteExpression to process them.
  283. //
  284. DefiniteAssignmentSet *Semantic::DefiniteDefaultPreUnaryExpression(AstExpression *expr, BitSet &set)
  285. {
  286.     return (this ->* DefiniteExpr[expr -> kind])(expr, set);
  287. }
  288.  
  289.  
  290. DefiniteAssignmentSet *Semantic::DefinitePreUnaryExpression(AstExpression *expression, BitSet &set)
  291. {
  292.     AstPreUnaryExpression *prefix_expression = (AstPreUnaryExpression *) expression;
  293.     return (this ->* DefinitePreUnaryExpr[prefix_expression -> pre_unary_tag])(prefix_expression -> expression, set);
  294. }
  295.  
  296.  
  297. DefiniteAssignmentSet *Semantic::DefiniteAssignmentAND(TypeSymbol *type,
  298.                                                        BitSet *before_right,
  299.                                                        BitSet &set,
  300.                                                        DefiniteAssignmentSet *after_left,
  301.                                                        DefiniteAssignmentSet *after_right)
  302. {
  303.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  304.     {
  305.         if (! after_left)
  306.         {
  307.             after_left = new DefiniteAssignmentSet(universe -> Size());
  308.             after_left -> true_set = *before_right;
  309.             after_left -> false_set = *before_right;
  310.         }
  311.  
  312.         if (! after_right)
  313.         {
  314.             after_right = new DefiniteAssignmentSet(universe -> Size());
  315.             after_right -> true_set = set;
  316.             after_right -> false_set = set;
  317.         }
  318.  
  319.         after_left -> true_set += after_right -> true_set;   // definitely assigned after left when true and after right when true
  320.         after_left -> false_set *= after_right -> false_set; // definitely assigned after left when false and after right when false
  321.         after_right -> true_set *= after_right -> false_set; // definitely assigned after right
  322.         after_left -> false_set += after_right -> true_set;
  323.  
  324.         delete after_right;
  325.     }
  326.  
  327.     delete before_right; // nothing happens if before_right is null
  328.  
  329.     return after_left;
  330. }
  331.  
  332.  
  333. DefiniteAssignmentSet *Semantic::DefiniteAssignmentIOR(TypeSymbol *type,
  334.                                                        BitSet *before_right,
  335.                                                        BitSet &set,
  336.                                                        DefiniteAssignmentSet *after_left,
  337.                                                        DefiniteAssignmentSet *after_right)
  338. {
  339.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  340.     {
  341.         if (! after_left)
  342.         {
  343.             after_left = new DefiniteAssignmentSet(universe -> Size());
  344.             after_left -> true_set = *before_right;
  345.             after_left -> false_set = *before_right;
  346.         }
  347.  
  348.         if (! after_right)
  349.         {
  350.             after_right = new DefiniteAssignmentSet(universe -> Size());
  351.             after_right -> true_set = set;
  352.             after_right -> false_set = set;
  353.         }
  354.  
  355.         after_left -> true_set *= after_right -> true_set;   // after a when true and after b when true
  356.         after_right -> true_set *= after_right -> false_set; // definitely assigned after b
  357.         after_left -> true_set += after_right -> true_set;
  358.         after_left -> false_set += after_right -> false_set; // after a when false or after b when false
  359.  
  360.         delete after_right;
  361.     }
  362.  
  363.     delete before_right; // nothing happens if before_right is null
  364.  
  365.     return after_left;
  366. }
  367.  
  368.  
  369. DefiniteAssignmentSet *Semantic::DefiniteAssignmentXOR(TypeSymbol *type,
  370.                                                        BitSet *before_right,
  371.                                                        BitSet &set,
  372.                                                        DefiniteAssignmentSet *after_left,
  373.                                                        DefiniteAssignmentSet *after_right)
  374. {
  375.     DefiniteAssignmentSet *definite = NULL;
  376.  
  377.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  378.     {
  379.         definite = new DefiniteAssignmentSet(universe -> Size());
  380.  
  381.         if (! after_left)
  382.         {
  383.             after_left = new DefiniteAssignmentSet(universe -> Size());
  384.             after_left -> true_set = *before_right;
  385.             after_left -> false_set = *before_right;
  386.         }
  387.  
  388.         if (! after_right)
  389.         {
  390.             after_right = new DefiniteAssignmentSet(universe -> Size());
  391.             after_right -> true_set = set;
  392.             after_right -> false_set = set;
  393.         }
  394.  
  395.         //
  396.         // compute definitely assigned after right.
  397.         //
  398.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  399.  
  400.         //
  401.         // compute definitely assigned after left when true and after right when true
  402.         // compute definitely assigned after left when false and after right when false
  403.         // add the union of these two sets to true_set;
  404.         //
  405.         definite -> true_set += (after_left -> true_set * after_right -> true_set)
  406.                               + (after_left -> false_set * after_right -> false_set);
  407.         //
  408.         // compute definitely assigned after left when true and after right when false
  409.         // compute definitely assigned after left when false and after right when true
  410.         // add the union of these two sets to false_set;
  411.         //
  412.         definite -> false_set += (after_left -> true_set * after_right -> false_set)
  413.                                + (after_left -> false_set * after_right -> true_set);
  414.  
  415.         delete after_left;
  416.         delete after_right;
  417.     }
  418.  
  419.     delete before_right;  // nothing happens if before_right is NULL
  420.  
  421.     return definite;
  422. }
  423.  
  424.  
  425. DefiniteAssignmentSet *Semantic::DefiniteAND(AstBinaryExpression *expr, BitSet &set)
  426. {
  427.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  428.     BitSet *before_right = NULL;
  429.     if (after_left)
  430.          set = after_left -> true_set * after_left -> false_set;
  431.     else before_right = new BitSet(set);
  432.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  433.  
  434.     return DefiniteAssignmentAND(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  435. }
  436.  
  437.  
  438. DefiniteAssignmentSet *Semantic::DefiniteIOR(AstBinaryExpression *expr, BitSet &set)
  439. {
  440.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  441.     BitSet *before_right = NULL;
  442.     if (after_left)
  443.          set = after_left -> true_set * after_left -> false_set;
  444.     else before_right = new BitSet(set);
  445.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  446.  
  447.     return DefiniteAssignmentIOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  448. }
  449.  
  450.  
  451. DefiniteAssignmentSet *Semantic::DefiniteXOR(AstBinaryExpression *expr, BitSet &set)
  452. {
  453.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  454.     BitSet *before_right = NULL;
  455.     if (after_left)
  456.          set = after_left -> true_set * after_left -> false_set;
  457.     else before_right = new BitSet(set);
  458.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  459.  
  460.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  461. }
  462.  
  463.  
  464. DefiniteAssignmentSet *Semantic::DefiniteAND_AND(AstBinaryExpression *expr, BitSet &set)
  465. {
  466.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  467.     BitSet *before_right = NULL;
  468.     if (after_left)
  469.          set = after_left -> true_set;
  470.     else before_right = new BitSet(set);
  471.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  472.  
  473.     if (after_left)
  474.     {
  475.         if (after_right)
  476.         {
  477.             after_left -> true_set += after_right -> true_set;
  478.             after_left -> false_set *= after_right -> false_set;
  479.             delete after_right;
  480.         }
  481.         else
  482.         {
  483.             after_left -> true_set += set;
  484.             after_left -> false_set *= set;
  485.         }
  486.  
  487.         after_right = after_left;
  488.     }
  489.     else
  490.     {
  491.         if (! after_right)
  492.         {
  493.             after_right = new DefiniteAssignmentSet(universe -> Size());
  494.  
  495.             after_right -> true_set = set;
  496.             after_right -> false_set = set;
  497.         }
  498.         after_right -> true_set += *before_right;
  499.         after_right -> false_set *= *before_right;
  500.  
  501.         delete before_right;
  502.     }
  503.  
  504.     return after_right;
  505. }
  506.  
  507.  
  508. DefiniteAssignmentSet *Semantic::DefiniteOR_OR(AstBinaryExpression *expr, BitSet &set)
  509. {
  510.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  511.     BitSet *before_right = NULL;
  512.     if (after_left)
  513.          set = after_left -> false_set;
  514.     else before_right = new BitSet(set);
  515.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  516.  
  517.     if (after_left)
  518.     {
  519.         if (after_right)
  520.         {
  521.             after_left -> true_set *= after_right -> true_set;
  522.             after_left -> false_set += after_right -> false_set;
  523.             delete after_right;
  524.         }
  525.         else
  526.         {
  527.             after_left -> true_set *= set;
  528.             after_left -> false_set += set;
  529.         }
  530.  
  531.         after_right = after_left;
  532.     }
  533.     else
  534.     {
  535.         if (! after_right)
  536.         {
  537.             after_right = new DefiniteAssignmentSet(universe -> Size());
  538.  
  539.             after_right -> true_set = set;
  540.             after_right -> false_set = set;
  541.         }
  542.         after_right -> true_set *= *before_right;
  543.         after_right -> false_set += *before_right;
  544.  
  545.         delete before_right;
  546.     }
  547.  
  548.     return after_right;
  549. }
  550.  
  551.  
  552. DefiniteAssignmentSet *Semantic::DefiniteEQUAL_EQUAL(AstBinaryExpression *expr, BitSet &set)
  553. {
  554.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  555.     BitSet *before_right = NULL;
  556.     if (after_left)
  557.          set = after_left -> true_set * after_left -> false_set;
  558.     else before_right = new BitSet(set);
  559.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  560.  
  561.     DefiniteAssignmentSet *definite = NULL;
  562.  
  563.     if (after_left || after_right) // one of the subexpressions is a complex boolean expression
  564.     {
  565.         definite = new DefiniteAssignmentSet(universe -> Size());
  566.  
  567.         if (! after_left)
  568.         {
  569.             after_left = new DefiniteAssignmentSet(universe -> Size());
  570.             after_left -> true_set = *before_right;
  571.             after_left -> false_set = *before_right;
  572.         }
  573.  
  574.         if (! after_right)
  575.         {
  576.             after_right = new DefiniteAssignmentSet(universe -> Size());
  577.             after_right -> true_set = set;
  578.             after_right -> false_set = set;
  579.         }
  580.  
  581.         //
  582.         // compute definitely assigned after right.
  583.         //
  584.         definite -> true_set = definite -> false_set = (after_right -> true_set * after_right -> false_set);
  585.  
  586.         //
  587.         // compute definitely assigned after left when true and after right when false
  588.         // compute definitely assigned after left when false and after right when true
  589.         // and add their union to true_set
  590.         //
  591.         definite -> true_set += (after_left -> true_set * after_right -> false_set)
  592.                               + (after_left -> false_set * after_right -> true_set);
  593.  
  594.         //
  595.         // compute definitely assigned after left when true and after right when true
  596.         // compute definitely assigned after left when false and after right when false
  597.         // and add their union to false_set
  598.         //
  599.         definite -> false_set += (after_left -> true_set * after_right -> true_set)
  600.                                + (after_left -> false_set * after_right -> false_set);
  601.  
  602.         delete after_left;
  603.         delete after_right;
  604.     }
  605.  
  606.     delete before_right; // nothing happens if before_right is NULL
  607.  
  608.     return definite;
  609. }
  610.  
  611.  
  612. DefiniteAssignmentSet *Semantic::DefiniteNOT_EQUAL(AstBinaryExpression *expr, BitSet &set)
  613. {
  614.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  615.     BitSet *before_right = NULL;
  616.     if (after_left)
  617.          set = after_left -> true_set * after_left -> false_set;
  618.     else before_right = new BitSet(set);
  619.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  620.  
  621.     //
  622.     // NOT_EQUAL has same definite assignment rules as XOR
  623.     //
  624.     return DefiniteAssignmentXOR(expr -> left_expression -> Type(), before_right, set, after_left, after_right);
  625. }
  626.  
  627.  
  628. DefiniteAssignmentSet *Semantic::DefiniteDefaultBinaryExpression(AstBinaryExpression *expr, BitSet &set)
  629. {
  630.     DefiniteAssignmentSet *after_left = DefiniteExpression(expr -> left_expression, set);
  631.     if (after_left) // if this is true there was a mistake !!!
  632.     {
  633.         set = after_left -> true_set * after_left -> false_set;
  634.         delete after_left;
  635.     }
  636.  
  637.     DefiniteAssignmentSet *after_right = DefiniteExpression(expr -> right_expression, set);
  638.     if (after_right) // if this is true there was a mistake !!!
  639.     {
  640.         set = (after_right -> true_set * after_right -> false_set);
  641.         delete after_right;
  642.     }
  643.  
  644.     return (DefiniteAssignmentSet *) NULL;
  645. }
  646.  
  647.  
  648. DefiniteAssignmentSet *Semantic::DefiniteBinaryExpression(AstExpression *expression, BitSet &set)
  649. {
  650.     AstBinaryExpression *binary_expression = (AstBinaryExpression *) expression;
  651.     return (this ->* DefiniteBinaryExpr[binary_expression -> binary_tag])(binary_expression, set);
  652. }
  653.  
  654.  
  655. DefiniteAssignmentSet *Semantic::DefiniteConditionalExpression(AstExpression *expression, BitSet &set)
  656. {
  657.     AstConditionalExpression *conditional_expression = (AstConditionalExpression *) expression;
  658.  
  659.     DefiniteAssignmentSet *after_condition = DefiniteExpression(conditional_expression -> test_expression, set);
  660.     BitSet *before_expressions = NULL;
  661.  
  662.     if (after_condition)
  663.          set = after_condition -> true_set;
  664.     else before_expressions = new BitSet(set);
  665.     DefiniteAssignmentSet *after_true = DefiniteExpression(conditional_expression -> true_expression, set);
  666.     BitSet *after_true_set = (BitSet *) (after_true ? NULL : new BitSet(set));
  667.  
  668.     if (after_condition)
  669.          set = after_condition -> false_set;
  670.     else set = *before_expressions;
  671.     DefiniteAssignmentSet *after_false = DefiniteExpression(conditional_expression -> false_expression, set);
  672.  
  673.     DefiniteAssignmentSet *definite = NULL;
  674.  
  675.     if (conditional_expression -> Type() == control.boolean_type)
  676.     {
  677.         definite = new DefiniteAssignmentSet(universe -> Size());
  678.  
  679.         //
  680.         //
  681.         //
  682.         if (after_true)
  683.         {
  684.             //
  685.             // before "true" expr or after it when true
  686.             //
  687.             definite -> true_set = after_true -> true_set + (after_condition ? after_condition -> true_set : *before_expressions);
  688.         }
  689.         else definite -> true_set = *after_true_set;
  690.  
  691.         if (after_false)
  692.         {
  693.             //
  694.             // before "false" expr or after it when true
  695.             //
  696.             definite -> true_set *= (after_false -> true_set +
  697.                                     (after_condition ? after_condition -> false_set : *before_expressions));
  698.         }
  699.         else definite -> true_set *= set;
  700.  
  701.         //
  702.         //
  703.         //
  704.         if (after_true)
  705.         {
  706.             //
  707.             // before "true" expr or after it when false
  708.             //
  709.             definite -> false_set = after_true -> false_set + (after_condition ? after_condition -> true_set : *before_expressions);
  710.         }
  711.         else definite -> false_set = *after_true_set;
  712.  
  713.         if (after_false)
  714.         {
  715.             //
  716.             // before "false" expr or after it when true
  717.             //
  718.             definite -> true_set *= (after_false -> false_set +
  719.                                      (after_condition ? after_condition -> false_set : *before_expressions));
  720.         }
  721.         else definite -> false_set *= set;
  722.     }
  723.     else
  724.     {
  725.         if (after_false)
  726.             set = after_false -> true_set * after_false -> false_set; // definitely assigned after the false expression ...
  727.  
  728.         // ... and definitely assigned after the true expression
  729.         if (after_true)
  730.              set *= (after_true -> true_set * after_true -> false_set);
  731.         else set *= *after_true_set;
  732.     }
  733.  
  734.     delete after_condition;    // nothing happens if after_condition is NULL
  735.     delete before_expressions; // nothing happens if before_expressions is NULL
  736.     delete after_true;         // nothing happens if after_true is NULL
  737.     delete after_true_set;     // nothing happens if after_true_set is NULL
  738.     delete after_false;        // nothing happens if after_false is NULL
  739.  
  740.     return definite;
  741. }
  742.  
  743.  
  744. DefiniteAssignmentSet *Semantic::DefiniteAssignmentExpression(AstExpression *expression, BitSet &set)
  745. {
  746.     AstAssignmentExpression *assignment_expression = (AstAssignmentExpression *) expression;
  747.  
  748.     AstExpression *left_hand_side = assignment_expression -> left_hand_side;
  749.     AstSimpleName *simple_name = left_hand_side -> SimpleNameCast();
  750.     if (simple_name)
  751.     {
  752.         if (simple_name -> resolution_opt)
  753.         {
  754.             left_hand_side = simple_name -> resolution_opt;
  755.             simple_name = left_hand_side -> SimpleNameCast();
  756.         }
  757.     }
  758.     else
  759.     {
  760.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  761.         if (field_access && field_access -> resolution_opt)
  762.             left_hand_side = field_access -> resolution_opt;
  763.     }
  764.  
  765.     VariableSymbol *variable = (left_hand_side -> symbol ? left_hand_side -> symbol -> VariableCast() : (VariableSymbol *) NULL);
  766.  
  767.     //
  768.     // An array access is never considered to be final. Since no variable
  769.     // is associated with the array access, the testing for the presence of variable
  770.     // takes care of that possibility.
  771.     //
  772.     if (variable)
  773.     {
  774.         if (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType()))
  775.         {
  776.             //
  777.             // If the debug option "g" is set and we have a simple assignment
  778.             // statement whose left-hand side is a local variable that has not
  779.             // yet been defined, mark this assignment as a definition assignment.
  780.             //
  781.             if (control.option.g &&
  782.                 assignment_expression -> assignment_tag == AstAssignmentExpression::SIMPLE_EQUAL &&
  783.                 variable -> IsLocal(ThisMethod()) &&
  784.                 (! set[variable -> LocalVariableIndex()]))
  785.             {
  786.                 assignment_expression -> assignment_tag = AstAssignmentExpression::DEFINITE_EQUAL;
  787.                 definite_block_stack -> TopLocallyDefinedVariables() -> AddElement(variable -> LocalVariableIndex());
  788.                 AstBlock *block = definite_block_stack -> TopBlock();
  789.                 block -> AddLocallyDefinedVariable(variable);
  790. #ifdef DUMP
  791. Coutput << "(1) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  792.         << "\" is defined at line " << lex_stream -> Line(assignment_expression -> LeftToken())
  793.         << "\n";
  794. #endif
  795.             }
  796.  
  797.             //
  798.             // If we have a compound assignment then the variable must have
  799.             // been set prior to such an assignment. otherwise, an error occurs.
  800.             //
  801.             if (! (assignment_expression -> SimpleAssignment() || set[variable -> LocalVariableIndex()]))
  802.             {
  803.                 ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  804.                                assignment_expression -> left_hand_side -> LeftToken(),
  805.                                assignment_expression -> left_hand_side -> RightToken(),
  806.                                variable -> Name());
  807.             }
  808.             else if (variable -> ACC_FINAL())
  809.             {
  810.                 //
  811.                 // If the final variable may have already been initialized, issue an error.
  812.                 //
  813.                 if ((! assignment_expression -> SimpleAssignment()) ||
  814.                     ((*possibly_assigned_finals) [variable -> LocalVariableIndex()]))
  815.                 {
  816.                     ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  817.                                    assignment_expression -> left_hand_side -> LeftToken(),
  818.                                    assignment_expression -> left_hand_side -> RightToken(),
  819.                                    variable -> Name());
  820.                 }
  821.                 else if (definite_final_assignment_stack -> Size() > 0) // are we processing the body of a loop ?
  822.                      definite_final_assignment_stack -> Top().Next() = left_hand_side;
  823.             }
  824.         }
  825.         else if (variable -> ACC_FINAL()) // attempt to assign a value to a final field member!
  826.         {
  827.             ReportSemError(SemanticError::TARGET_VARIABLE_IS_FINAL,
  828.                            assignment_expression -> left_hand_side -> LeftToken(),
  829.                            assignment_expression -> left_hand_side -> RightToken(),
  830.                            variable -> Name());
  831.         }
  832.     }
  833.  
  834.     DefiniteAssignmentSet *after_left = NULL;
  835.     BitSet *before_right = NULL;
  836.     //
  837.     // The left-hand-side of an assignment expression is either a simple name,
  838.     // a field access or an array access.
  839.     //
  840.     if (! simple_name)
  841.     {
  842.         AstFieldAccess *field_access = left_hand_side -> FieldAccessCast();
  843.         after_left = DefiniteExpression((field_access ? field_access -> base : left_hand_side), set);
  844.     }
  845.  
  846.     if (after_left)
  847.          set = after_left -> true_set * after_left -> false_set;
  848.     else before_right = new BitSet(set);
  849.  
  850.     DefiniteAssignmentSet *after_right = DefiniteExpression(assignment_expression -> expression, set);
  851.  
  852.     if (left_hand_side -> Type() == control.boolean_type)
  853.     {
  854.         DefiniteAssignmentSet *definite = NULL;
  855.  
  856.         if (assignment_expression -> assignment_tag == AstAssignmentExpression::AND_EQUAL)
  857.              definite = DefiniteAssignmentAND(control.boolean_type, before_right, set, after_left, after_right);
  858.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::XOR_EQUAL)
  859.              definite = DefiniteAssignmentXOR(control.boolean_type, before_right, set, after_left, after_right);
  860.         else if (assignment_expression -> assignment_tag == AstAssignmentExpression::IOR_EQUAL)
  861.              definite = DefiniteAssignmentIOR(control.boolean_type, before_right, set, after_left, after_right);
  862.         else
  863.         {
  864.             delete after_left;
  865.             delete before_right;
  866.             definite = after_right;
  867.         }
  868.  
  869.         if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  870.         {
  871.             if (definite)
  872.             {
  873.                 definite -> true_set.AddElement(variable -> LocalVariableIndex());
  874.                 definite -> false_set.AddElement(variable -> LocalVariableIndex());
  875.             }
  876.             else set.AddElement(variable -> LocalVariableIndex());
  877.  
  878.             if (variable -> ACC_FINAL())
  879.                 possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  880.         }
  881.  
  882.         return definite;
  883.     }
  884.  
  885.     if (after_right)
  886.         set = after_right -> true_set * after_right -> false_set;
  887.  
  888.     if (variable && (variable -> IsLocal(ThisMethod()) || variable -> IsFinal(ThisType())))
  889.     {
  890.         set.AddElement(variable -> LocalVariableIndex());
  891.         if (variable -> ACC_FINAL())
  892.             possibly_assigned_finals -> AddElement(variable -> LocalVariableIndex());
  893.     }
  894.  
  895.     delete after_left;   // nothing happens if after_left is NULL
  896.     delete before_right; // nothing happens if before_right is NULL
  897.     delete after_right;  // nothing happens if after_right is NULL
  898.  
  899.     return (DefiniteAssignmentSet *) NULL;
  900. }
  901.  
  902. DefiniteAssignmentSet *Semantic::DefiniteDefaultExpression(AstExpression *expr, BitSet &set)
  903. {
  904.     return (DefiniteAssignmentSet *) NULL;
  905. }
  906.  
  907. DefiniteAssignmentSet *Semantic::DefiniteParenthesizedExpression(AstExpression *expression, BitSet &set)
  908. {
  909.     AstParenthesizedExpression *expr = (AstParenthesizedExpression *) expression;
  910.  
  911.     return DefiniteExpression(expr -> expression, set);
  912. }
  913.  
  914. DefiniteAssignmentSet *Semantic::DefiniteFieldAccess(AstExpression *expression, BitSet &set)
  915. {
  916.     AstFieldAccess *expr = (AstFieldAccess *) expression;
  917.  
  918.     VariableSymbol *variable = DefiniteFinal(expr);
  919.     if (variable)
  920.     {
  921.         if (! set[variable -> LocalVariableIndex()])
  922.         {
  923.             ReportSemError(SemanticError::VARIABLE_NOT_DEFINITELY_ASSIGNED,
  924.                            expr -> LeftToken(),
  925.                            expr -> RightToken(),
  926.                            variable -> Name());
  927.             set.AddElement(variable -> LocalVariableIndex());
  928.         }
  929.     }
  930.  
  931.     return DefiniteExpression((expr -> resolution_opt ? expr -> resolution_opt : expr -> base), set);
  932. }
  933.  
  934. DefiniteAssignmentSet *Semantic::DefiniteCastExpression(AstExpression *expression, BitSet &set)
  935. {
  936.     AstCastExpression *expr = (AstCastExpression *) expression;
  937.  
  938.     return DefiniteExpression(expr -> expression, set);
  939. }
  940.  
  941. void Semantic::DefiniteArrayInitializer(AstArrayInitializer *array_initializer)
  942. {
  943.     for (int i = 0; i < array_initializer -> NumVariableInitializers(); i++)
  944.     {
  945.         AstArrayInitializer *sub_array_initializer = array_initializer -> VariableInitializer(i) -> ArrayInitializerCast();
  946.  
  947.         if (sub_array_initializer)
  948.             DefiniteArrayInitializer(sub_array_initializer);
  949.         else
  950.         {
  951.             AstExpression *init = (AstExpression *) array_initializer -> VariableInitializer(i);
  952.             DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  953.             if (after_init)
  954.             {
  955.                 *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  956.                 delete after_init;
  957.             }
  958.         }
  959.     }
  960.  
  961.     return;
  962. }
  963.  
  964.  
  965. inline void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator)
  966. {
  967.     AstArrayInitializer *array_initializer = variable_declarator -> variable_initializer_opt -> ArrayInitializerCast();
  968.     if (array_initializer)
  969.         DefiniteArrayInitializer(array_initializer);
  970.     else
  971.     {
  972.         AstExpression *init = (AstExpression *) variable_declarator -> variable_initializer_opt;
  973.         DefiniteAssignmentSet *after_init = DefiniteExpression(init, *definitely_assigned_variables);
  974.         if (after_init)
  975.         {
  976.             *definitely_assigned_variables = after_init -> true_set * after_init -> false_set;
  977.             delete after_init;
  978.         }
  979.     }
  980.  
  981.     return;
  982. }
  983.  
  984.  
  985. inline void Semantic::DefiniteStatement(Ast *ast)
  986. {
  987.     (this ->* DefiniteStmt[ast -> kind])(ast);
  988.  
  989.     return;
  990. }
  991.  
  992. inline void Semantic::DefiniteBlockStatements(AstBlock *block_body)
  993. {
  994.     if (control.option.g && block_body -> NumStatements() > 0)
  995.     {
  996.         AstStatement *statement = (AstStatement *) block_body -> Statement(0);
  997.         DefiniteStatement(statement);
  998.         for (int i = 1; i < block_body -> NumStatements(); i++)
  999.         {
  1000.             statement = (AstStatement *) block_body -> Statement(i);
  1001.             if (statement -> is_reachable)
  1002.             {
  1003.                 //
  1004.                 // All variables that were assigned a value in the previous
  1005.                 // statement must be defined
  1006.                 BitSet &locally_defined_variables = *definite_block_stack -> TopLocallyDefinedVariables();
  1007.                 for (int k = 0; k < definitely_assigned_variables -> Size(); k++)
  1008.                 {
  1009.                     VariableSymbol *variable = definite_block_stack -> TopLocalVariables()[k];
  1010.                     if (variable) // a variable that is visible in this block? (i.e. not one declare in a non-enclosing block)
  1011.                     {
  1012.                         if ((*definitely_assigned_variables)[k] && (! locally_defined_variables[k]))
  1013.                         {
  1014. #ifdef DUMP
  1015. Coutput << "(2) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  1016.         << "\" is defined at line " << lex_stream -> Line(statement -> LeftToken())
  1017.         << "\n";
  1018. #endif
  1019.                             statement -> AddDefinedVariable(variable);
  1020.                             locally_defined_variables.AddElement(k);
  1021.                             block_body -> AddLocallyDefinedVariable(variable);
  1022.                         }
  1023.                     }
  1024.                 }
  1025.  
  1026.                 DefiniteStatement(statement);
  1027.             }
  1028.             else break;
  1029.         }
  1030.     }
  1031.     else
  1032.     {
  1033.         for (int i = 0; i < block_body -> NumStatements(); i++)
  1034.         {
  1035.             AstStatement *statement = (AstStatement *) block_body -> Statement(i);
  1036.             if (statement -> is_reachable)
  1037.                  DefiniteStatement(statement);
  1038.             else break;
  1039.         }
  1040.     }
  1041.  
  1042.     return;
  1043. }
  1044.  
  1045.  
  1046. void Semantic::DefiniteBlock(Ast *stmt)
  1047. {
  1048.     AstBlock *block_body = (AstBlock *) stmt;
  1049.  
  1050.     definite_block_stack -> Push(block_body);
  1051.  
  1052.     for (int i = 0; i < block_body -> block_symbol -> NumVariableSymbols(); i++)
  1053.     {
  1054.         VariableSymbol *variable = block_body -> block_symbol -> VariableSym(i);
  1055.  
  1056.         possibly_assigned_finals -> RemoveElement(variable -> LocalVariableIndex());
  1057.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1058.  
  1059.         definite_visible_variables -> AddElement(variable);
  1060.     }
  1061.  
  1062.     DefiniteBlockStatements(block_body);
  1063.  
  1064. #ifdef DUMP
  1065. if (control.option.g && block_body -> NumLocallyDefinedVariables() > 0)
  1066. {
  1067. Coutput << "(3) At Line " << lex_stream -> Line(block_body -> RightToken())
  1068.         << " the range for the following variables end:\n\n";
  1069. for (int j = 0; j < block_body -> NumLocallyDefinedVariables(); j++)
  1070. Coutput << "    \"" << block_body -> LocallyDefinedVariable(j) -> Name() << "\"\n";
  1071. }
  1072. #endif
  1073.     for (int k = 0; k < block_body -> block_symbol -> NumVariableSymbols(); k++)
  1074.         definite_visible_variables -> RemoveElement(block_body -> block_symbol -> VariableSym(k));
  1075.  
  1076.     //
  1077.     // Note that in constructing the Ast, the parser encloses each
  1078.     // labeled statement in its own block... Therefore, only blocks
  1079.     // are labeled.
  1080.     //
  1081.     if (block_body -> NumLabels() > 0)
  1082.         *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1083.  
  1084.     definite_block_stack -> Pop();
  1085.  
  1086.     return;
  1087. }
  1088.  
  1089.  
  1090. void Semantic::DefiniteLocalVariableDeclarationStatement(Ast *stmt)
  1091. {
  1092.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  1093.  
  1094.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  1095.     {
  1096.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  1097.         VariableSymbol *variable_symbol = variable_declarator -> symbol;
  1098.         if (variable_symbol)
  1099.         {
  1100.             if (control.option.g)
  1101.             {
  1102.                 assert(definite_block_stack -> TopLocalVariables()[variable_symbol -> LocalVariableIndex()] == NULL);
  1103. #ifdef DUMP
  1104. Coutput << "(3.5) Local Variable \"" << variable_symbol -> Name() << " #" << variable_symbol -> LocalVariableIndex()
  1105.         << "\" is declared at line " << lex_stream -> Line(variable_declarator -> LeftToken())
  1106.         << "\n";
  1107. #endif
  1108.                 definite_block_stack -> TopLocalVariables()[variable_symbol -> LocalVariableIndex()] = variable_symbol;
  1109.             }
  1110.  
  1111.             if (variable_declarator -> variable_initializer_opt)
  1112.             {
  1113.                 DefiniteVariableInitializer(variable_declarator);
  1114.                 definitely_assigned_variables -> AddElement(variable_symbol -> LocalVariableIndex());
  1115.                 if (variable_symbol -> ACC_FINAL())
  1116.                     possibly_assigned_finals -> AddElement(variable_symbol -> LocalVariableIndex());
  1117.  
  1118.                 if (control.option.g)
  1119.                 {
  1120.                     definite_block_stack -> TopLocallyDefinedVariables() -> AddElement(variable_symbol -> LocalVariableIndex());
  1121.                     AstBlock *block = definite_block_stack -> TopBlock();
  1122.                     block -> AddLocallyDefinedVariable(variable_symbol);
  1123. #ifdef DUMP
  1124. Coutput << "(4) Variable \"" << variable_symbol -> Name() << " #" << variable_symbol -> LocalVariableIndex()
  1125.         << "\" is defined at line " << lex_stream -> Line(variable_declarator -> LeftToken())
  1126.         << "\n";
  1127. #endif
  1128.                 }
  1129.             }
  1130.             else definitely_assigned_variables -> RemoveElement(variable_symbol -> LocalVariableIndex());
  1131.         }
  1132.     }
  1133.  
  1134.     return;
  1135. }
  1136.  
  1137.  
  1138. void Semantic::DefiniteExpressionStatement(Ast *stmt)
  1139. {
  1140.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  1141.  
  1142.     DefiniteAssignmentSet *after_expr = DefiniteExpression(expression_statement -> expression, *definitely_assigned_variables);
  1143.     if (after_expr)
  1144.     {
  1145.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1146.         delete after_expr;
  1147.     }
  1148.  
  1149.    return;
  1150. }
  1151.  
  1152.  
  1153. void Semantic::DefiniteSynchronizedStatement(Ast *stmt)
  1154. {
  1155.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  1156.  
  1157.     DefiniteAssignmentSet *after_expr = DefiniteExpression(synchronized_statement -> expression, *definitely_assigned_variables);
  1158.     if (after_expr)
  1159.     {
  1160.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1161.         delete after_expr;
  1162.     }
  1163.  
  1164.     DefiniteBlock(synchronized_statement -> block);
  1165.  
  1166.     return;
  1167. }
  1168.  
  1169.  
  1170. void Semantic::DefiniteIfStatement(Ast *stmt)
  1171. {
  1172.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  1173.  
  1174.     DefiniteAssignmentSet *after_expr = DefiniteExpression(if_statement -> expression, *definitely_assigned_variables);
  1175.     BitSet after_expr_finals(*possibly_assigned_finals);
  1176.     BitSet *starting_set = (after_expr ? (BitSet *) NULL : new BitSet(*definitely_assigned_variables));
  1177.     if (after_expr)
  1178.          *definitely_assigned_variables = after_expr -> true_set;
  1179.  
  1180.     //
  1181.     // If the expression in the if-statement is a boolean constant expression then get its value.
  1182.     //
  1183.     IntLiteralValue *if_constant_expr = (if_statement -> expression -> Type() == control.boolean_type &&
  1184.                                          if_statement -> expression -> IsConstant()
  1185.                                                                      ? (IntLiteralValue *) if_statement -> expression -> value
  1186.                                                                      : (IntLiteralValue *) NULL);
  1187.     //
  1188.     // If either the expression is not constant or its value is true, then
  1189.     // check the statement that make up the true part of the if statement
  1190.     //
  1191.     if ((! if_constant_expr) || if_constant_expr -> value)
  1192.         DefiniteBlock(if_statement -> true_statement);
  1193.  
  1194.     //
  1195.     // Recall that the parser ensures that the statements that appear in an if-statement
  1196.     // (both the true and false statement) are enclosed in a block.
  1197.     //
  1198.     if (! if_statement -> false_statement_opt) // no else part ?
  1199.     {
  1200.         *definitely_assigned_variables *= (after_expr ? after_expr -> false_set : *starting_set);
  1201.         *possibly_assigned_finals += after_expr_finals;
  1202.     }
  1203.     else
  1204.     {
  1205.         BitSet after_true_finals(*possibly_assigned_finals);
  1206.         *possibly_assigned_finals = after_expr_finals;
  1207.  
  1208.         BitSet true_set(*definitely_assigned_variables);
  1209.         *definitely_assigned_variables = (after_expr ? after_expr -> false_set : *starting_set);
  1210.  
  1211.         if ((! if_constant_expr) || (! if_constant_expr -> value)) // either the expression is not constant or its value is false?
  1212.             DefiniteBlock(if_statement -> false_statement_opt);
  1213.  
  1214.         *definitely_assigned_variables *= true_set;
  1215.         *possibly_assigned_finals += after_true_finals;
  1216.     }
  1217.  
  1218.     delete after_expr;   // nothing happens if after_expr is NULL
  1219.     delete starting_set; // nothing happens if starting_set is NULL
  1220.  
  1221.     return;
  1222. }
  1223.  
  1224.  
  1225. void Semantic::DefiniteLoopBody(AstStatement *statement)
  1226. {
  1227.     definite_final_assignment_stack -> Push();
  1228.  
  1229.     BitSet starting_set(*possibly_assigned_finals);
  1230.  
  1231.     DefiniteStatement(statement);
  1232.  
  1233.     BitSet exit_set(*possibly_assigned_finals);
  1234.     exit_set += definite_block_stack -> TopFinalContinueSet();
  1235.  
  1236.     //
  1237.     // The set of variables that may have been possibly assigned within the body of a loop
  1238.     // consists of the set of variables that was possibly assigned at the end of the block
  1239.     // UNION the set of variables that was possibly assigned prior to a continue statement
  1240.     // within the body of the loop MINUS the set of variables that were possibly assigned
  1241.     // prior to entering the loop.
  1242.     //
  1243.     BitSet new_set(exit_set);
  1244.     new_set -= starting_set;
  1245.  
  1246.     for (int k = 0; k < definite_final_assignment_stack -> Top().Length(); k++)
  1247.     {
  1248.         AstExpression *name = definite_final_assignment_stack -> Top()[k];
  1249.         VariableSymbol *variable = (VariableSymbol *) name -> symbol;
  1250.  
  1251.         if (definite_visible_variables -> IsElement(variable) && new_set[variable -> LocalVariableIndex()])
  1252.         {
  1253.             ReportSemError(SemanticError::FINAL_VARIABLE_TARGET_IN_LOOP,
  1254.                            name -> LeftToken(),
  1255.                            name -> RightToken(),
  1256.                            variable -> Name());
  1257.         }
  1258.     }
  1259.  
  1260.     exit_set += definite_block_stack -> TopFinalBreakSet();
  1261.     *possibly_assigned_finals = exit_set;
  1262.     definite_final_assignment_stack -> Pop();
  1263.  
  1264.     return;
  1265. }
  1266.  
  1267.  
  1268. void Semantic::DefiniteWhileStatement(Ast *stmt)
  1269. {
  1270.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  1271.  
  1272.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1273.     ContinuableStatementStack().Push(stmt);
  1274.  
  1275.     DefiniteAssignmentSet *after_expr = DefiniteExpression(while_statement -> expression, *definitely_assigned_variables);
  1276.  
  1277.     bool while_expr = true;
  1278.     if (while_statement -> expression -> Type() == control.boolean_type && while_statement -> expression -> IsConstant())
  1279.     {
  1280.         IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  1281.         if (! literal -> value)
  1282.             while_expr = false;
  1283.     }
  1284.  
  1285.     if (after_expr)
  1286.     {
  1287.         *definitely_assigned_variables = after_expr -> true_set;
  1288.         //
  1289.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1290.         //
  1291.         if (while_expr)
  1292.             DefiniteLoopBody(while_statement -> statement);
  1293.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1294.         delete after_expr;
  1295.     }
  1296.     else
  1297.     {
  1298.         BitSet starting_set(*definitely_assigned_variables);
  1299.         //
  1300.         // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1301.         //
  1302.         if (while_expr)
  1303.             DefiniteLoopBody(while_statement -> statement);
  1304.         *definitely_assigned_variables = (starting_set * definite_block_stack -> TopBreakSet());
  1305.     }
  1306.  
  1307.     ContinuableStatementStack().Pop();
  1308.     BreakableStatementStack().Pop();
  1309.  
  1310.     return;
  1311. }
  1312.  
  1313.  
  1314. void Semantic::DefiniteForStatement(Ast *stmt)
  1315. {
  1316.     AstForStatement *for_statement = (AstForStatement *) stmt;
  1317.  
  1318.     //
  1319.     // Note that in constructing the Ast, the parser encloses each
  1320.     // for-statement whose for-init-statements starts with a local
  1321.     // variable declaration in its own block. Therefore a redeclaration
  1322.     // of another local variable with the same name in a different loop
  1323.     // at the same nesting level will not cause any conflict.
  1324.     //
  1325.     // For example, the following sequence of statements is legal:
  1326.     //
  1327.     //     for (int i = 0; i < 10; i++);
  1328.     //     for (int i = 10; i < 20; i++);
  1329.     //
  1330.     if (control.option.g && for_statement -> NumForInitStatements() > 0)
  1331.     {
  1332.         AstStatement *statement = (AstStatement *) for_statement -> ForInitStatement(0);
  1333.         DefiniteStatement(statement);
  1334.         for (int i = 1; i < for_statement -> NumForInitStatements(); i++)
  1335.         {
  1336.             statement = (AstStatement *) for_statement -> ForInitStatement(i);
  1337.  
  1338.             //
  1339.             // All variables that were assigned a value in the previous
  1340.             // statement must be defined
  1341.             //
  1342.             BitSet &locally_defined_variables = *definite_block_stack -> TopLocallyDefinedVariables();
  1343.             for (int k = 0; k < definitely_assigned_variables -> Size(); k++)
  1344.             {
  1345.                 VariableSymbol *variable = definite_block_stack -> TopLocalVariables()[k];
  1346.                 if (variable) // a variable that is visible in this block? (i.e. not one declare in a non-enclosing block)
  1347.                 {
  1348.                     if ((*definitely_assigned_variables)[k] && (! locally_defined_variables[k]))
  1349.                     {
  1350. #ifdef DUMP
  1351. Coutput << "(5) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  1352.         << "\" is defined at line " << lex_stream -> Line(statement -> LeftToken())
  1353.         << "\n";
  1354. #endif
  1355.                         statement -> AddDefinedVariable(variable);
  1356.                         locally_defined_variables.AddElement(k);
  1357.                         AstBlock *block = definite_block_stack -> TopBlock();
  1358.                         block -> AddLocallyDefinedVariable(variable);
  1359.                     }
  1360.                 }
  1361.             }
  1362.  
  1363.             DefiniteStatement(statement);
  1364.         }
  1365.     }
  1366.     else
  1367.     {
  1368.         for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  1369.         {
  1370.             DefiniteStatement(for_statement -> ForInitStatement(i));
  1371.         }
  1372.     }
  1373.  
  1374.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1375.     ContinuableStatementStack().Push(stmt);
  1376.  
  1377.     DefiniteAssignmentSet *after_end_expression = NULL;
  1378.     BitSet before_statement(universe -> Size());
  1379.  
  1380.     bool for_expr = true;
  1381.     if (for_statement -> end_expression_opt)
  1382.     {
  1383.         after_end_expression = DefiniteExpression(for_statement -> end_expression_opt, *definitely_assigned_variables);
  1384.  
  1385.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type &&
  1386.             for_statement -> end_expression_opt -> IsConstant())
  1387.         {
  1388.             IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  1389.             if (! literal -> value)
  1390.                 for_expr = false;
  1391.         }
  1392.     }
  1393.  
  1394.     if (after_end_expression)
  1395.          *definitely_assigned_variables = after_end_expression -> true_set;
  1396.     else before_statement = *definitely_assigned_variables;
  1397.  
  1398.     //
  1399.     // If the expression is always false, the body of the loop is not reachable and therefore will never execute.
  1400.     //
  1401.     if (for_expr)
  1402.         DefiniteLoopBody(for_statement -> statement);
  1403.  
  1404.     //
  1405.     // Compute the set of variables that are definitely assigned after the
  1406.     // contained statement and after every continue statement that may exit
  1407.     // the body of the for statement.
  1408.     //
  1409.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1410.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  1411.         DefiniteExpressionStatement(for_statement -> ForUpdateStatement(j));
  1412.  
  1413.     //
  1414.     // Compute the set of variables that belongs to both sets below:
  1415.     //
  1416.     //    . the universe if no condition expression is present;
  1417.     //      otherwise, the set of variables that is definitely assigned when
  1418.     //      the condition expression is false.
  1419.     //
  1420.     //    . the set of variables that is definitely assigned before every
  1421.     //      break statement that may exit the for statement.
  1422.     //
  1423.     *definitely_assigned_variables = (for_statement -> end_expression_opt
  1424.                                                      ? (after_end_expression ? after_end_expression -> false_set : before_statement)
  1425.                                                      : *universe); // set of variables that depend on the condition
  1426.  
  1427.     //
  1428.     // The replacement
  1429.     //
  1430.     *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1431.  
  1432.     delete after_end_expression; // nothing happens if after_end_expression is NULL
  1433.  
  1434.     ContinuableStatementStack().Pop();
  1435.     BreakableStatementStack().Pop();
  1436.  
  1437.     return;
  1438. }
  1439.  
  1440.  
  1441. void Semantic::DefiniteDoStatement(Ast *stmt)
  1442. {
  1443.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  1444.  
  1445.     BreakableStatementStack().Push(definite_block_stack -> TopBlock());
  1446.     ContinuableStatementStack().Push(stmt);
  1447.  
  1448.     bool do_expr = true;
  1449.     if (do_statement -> expression -> Type() == control.boolean_type && do_statement -> expression -> IsConstant())
  1450.     {
  1451.         IntLiteralValue *literal = (IntLiteralValue *) do_statement -> expression -> value;
  1452.         if (! literal -> value)
  1453.             do_expr = false;
  1454.     }
  1455.  
  1456.     if (do_expr)
  1457.          DefiniteLoopBody(do_statement -> statement);
  1458.     else DefiniteStatement(do_statement -> statement); // The expression is always false therefore, loop will execute exactly once.
  1459.  
  1460.     BitSet after_stmt(*definitely_assigned_variables);
  1461.     *definitely_assigned_variables *= definite_block_stack -> TopContinueSet();
  1462.     DefiniteAssignmentSet *after_expr = DefiniteExpression(do_statement -> expression, *definitely_assigned_variables);
  1463.     if (after_expr)
  1464.     {
  1465.         *definitely_assigned_variables = (after_expr -> false_set * definite_block_stack -> TopBreakSet());
  1466.         delete after_expr;
  1467.     }
  1468.     else *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1469.  
  1470.     ContinuableStatementStack().Pop();
  1471.     BreakableStatementStack().Pop();
  1472.  
  1473.     return;
  1474. }
  1475.  
  1476.  
  1477. void Semantic::DefiniteSwitchStatement(Ast *stmt)
  1478. {
  1479.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  1480.  
  1481.     AstBlock *block_body = switch_statement -> switch_block;
  1482.     definite_block_stack -> Push(block_body);
  1483.     BreakableStatementStack().Push(block_body);
  1484.  
  1485.     DefiniteAssignmentSet *after_expr = DefiniteExpression(switch_statement -> expression, *definitely_assigned_variables);
  1486.     if (after_expr)
  1487.     {
  1488.         *definitely_assigned_variables = after_expr -> true_set * after_expr -> false_set;
  1489.         delete after_expr;
  1490.     }
  1491.  
  1492.     BitSet starting_set(*definitely_assigned_variables),
  1493.            after_expr_finals(*possibly_assigned_finals),
  1494.            switch_finals_union(*possibly_assigned_finals);
  1495.  
  1496.     for (int i = 0; i < block_body -> NumStatements(); i++)
  1497.     {
  1498.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  1499.  
  1500.         *definitely_assigned_variables = starting_set;
  1501.         *possibly_assigned_finals = after_expr_finals;
  1502.  
  1503.         if (control.option.g && switch_block_statement -> NumStatements() > 0)
  1504.         {
  1505.             BitSet &locally_defined_variables = *definite_block_stack -> TopLocallyDefinedVariables();
  1506.             AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(0);
  1507.             DefiniteStatement(statement);
  1508.             for (int i = 1; i < switch_block_statement -> NumStatements(); i++)
  1509.             {
  1510.                 statement = (AstStatement *) switch_block_statement -> Statement(i);
  1511.                 if (statement -> is_reachable)
  1512.                 {
  1513.                     //
  1514.                     // All variables that were assigned a value in the previous
  1515.                     // statement must be defined
  1516.                     //
  1517.                     for (int k = 0; k < definitely_assigned_variables -> Size(); k++)
  1518.                     {
  1519.                         VariableSymbol *variable = definite_block_stack -> TopLocalVariables()[k];
  1520.                         if (variable) // a variable that is visible in this block? (i.e. not one declare in a non-enclosing block)
  1521.                         {
  1522.                             if ((*definitely_assigned_variables)[k] && (! locally_defined_variables[k]))
  1523.                             {
  1524. #ifdef DUMP
  1525. Coutput << "Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  1526.         << "\" is defined at line " << lex_stream -> Line(statement -> LeftToken())
  1527.         << "\n";
  1528. #endif
  1529.                                 statement -> AddDefinedVariable(variable);
  1530.                                 locally_defined_variables.AddElement(k);
  1531.                                 block_body -> AddLocallyDefinedVariable(variable);
  1532.                             }
  1533.                         }
  1534.                     }
  1535.  
  1536.                     DefiniteStatement(statement);
  1537.                 }
  1538.                 else break;
  1539.             }
  1540.  
  1541. #ifdef DUMP
  1542. if (control.option.g && block_body -> NumLocallyDefinedVariables() > 0)
  1543. {
  1544. Coutput << "(5.5) At Line " << lex_stream -> Line(statement -> RightToken())
  1545.         << " the range for the following variables end:\n\n";
  1546. for (int j = 0; j < block_body -> NumLocallyDefinedVariables(); j++)
  1547. Coutput << "    \"" << block_body -> LocallyDefinedVariable(j) -> Name() << "\"\n";
  1548. }
  1549. #endif
  1550.             //
  1551.             // At the end of a switch block statement, we always close the range of all local
  1552.             // variables that have been defined. That's because even if this switch block statement
  1553.             // entends into the next block, it is not the only entry point into that block. Therefore,
  1554.             // in order for a variable to be definitely defined at the starting point of a switch
  1555.             // block statement, it must have been defined prior to the switch statement.
  1556.             //
  1557.             for (int k = 0; k < block_body -> NumLocallyDefinedVariables(); k++)
  1558.                 locally_defined_variables.RemoveElement(block_body -> LocallyDefinedVariable(k) -> LocalVariableIndex());
  1559.             block_body -> TransferLocallyDefinedVariablesTo(switch_block_statement);
  1560.         }
  1561.         else
  1562.         {
  1563.             for (int i = 0; i < switch_block_statement -> NumStatements(); i++)
  1564.             {
  1565.                 AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(i);
  1566.                 if (statement -> is_reachable)
  1567.                      DefiniteStatement(statement);
  1568.                 else break;
  1569.             }
  1570.         }
  1571.  
  1572.         //
  1573.         // Update possibly_assigned_finals here. If a continue, break (of an enclosing statement), return or throw
  1574.         // statement was encountered...
  1575.         //
  1576.         switch_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1577.     }
  1578.  
  1579.     if (switch_statement -> default_case.switch_block_statement) // Is there a default case?
  1580.          *definitely_assigned_variables *= definite_block_stack -> TopBreakSet();
  1581.     else *definitely_assigned_variables = starting_set;
  1582.  
  1583.     *possibly_assigned_finals = switch_finals_union;
  1584.  
  1585.     BreakableStatementStack().Pop();
  1586.     definite_block_stack -> Pop();
  1587.  
  1588.     return;
  1589. }
  1590.  
  1591.  
  1592. void Semantic::DefiniteBreakStatement(Ast *stmt)
  1593. {
  1594.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  1595.  
  1596.     //
  1597.     // Compute the set of variables that are definitely assigned prior to executing the break.
  1598.     //
  1599.     definite_block_stack -> BreakSet(break_statement -> nesting_level) *= (*definitely_assigned_variables);
  1600.     definite_block_stack -> FinalBreakSet(break_statement -> nesting_level) += (*possibly_assigned_finals);
  1601.  
  1602.     //
  1603.     // After execution of a break statement, it is vacuously true
  1604.     // that every variable has definitely been assigned and no final
  1605.     // variable has been possibly assigned (as nothing is reachable
  1606.     // any way).
  1607.     //
  1608.     *definitely_assigned_variables = *universe;
  1609.     possibly_assigned_finals -> SetEmpty();
  1610.  
  1611.     return;
  1612. }
  1613.  
  1614.  
  1615. void Semantic::DefiniteContinueStatement(Ast *stmt)
  1616. {
  1617.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  1618.  
  1619.     //
  1620.     // Compute the set of variables that are definitely assigned prior to executing the continue.
  1621.     //
  1622.     definite_block_stack -> ContinueSet(continue_statement -> nesting_level) *= (*definitely_assigned_variables);
  1623.     definite_block_stack -> FinalContinueSet(continue_statement -> nesting_level) += (*possibly_assigned_finals);
  1624.  
  1625.     //
  1626.     // After execution of a continue statement, it is vacuously true
  1627.     // that every variable has definitely been assigned and no final
  1628.     // variable has been possibly assigned (as nothing is reachable
  1629.     // any way).
  1630.     //
  1631.     *definitely_assigned_variables = *universe;
  1632.     possibly_assigned_finals -> SetEmpty();
  1633.  
  1634.     return;
  1635. }
  1636.  
  1637.  
  1638. void Semantic::DefiniteReturnStatement(Ast *stmt)
  1639. {
  1640.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  1641.  
  1642.     if (return_statement -> expression_opt)
  1643.     {
  1644.         DefiniteAssignmentSet *after_expr = DefiniteExpression(return_statement -> expression_opt, *definitely_assigned_variables);
  1645.         if (after_expr)
  1646.             delete after_expr;
  1647.     }
  1648.  
  1649.     //
  1650.     // Compute the set of variables that are definitely assigned prior to executing
  1651.     // this return statement. Note that this set is only relevant to the method or
  1652.     // constructor block containing this statement.
  1653.     //
  1654.     // TODO: Do we really need this?
  1655.     //
  1656.     //    definite_block_stack -> TopReturnSet() *= (*definitely_assigned_variables);
  1657.     //
  1658.  
  1659.     //
  1660.     // Compute the set of variables that are possibly assigned prior to executing this return statement.
  1661.     // We have a few cases to consider:
  1662.     //
  1663.     //    1. The return statement is not contained in a try statement - the possibly-assigned set is only relevant
  1664.     //       to the enclosing method (or constructor) block. The definitely assigned set is updated as if the return
  1665.     //       statement was a break statement out of the method (or constructor) block.
  1666.     //
  1667.     //    2. If the return statement is contained in a try main block or a try
  1668.     //       catch block that contains a finally clause - the possibly-assigned
  1669.     //       block is relevant to that main try block or catch block.
  1670.     //
  1671.     //    3. otherwise, treat the return statement as if it immediately followed its containing try statement
  1672.     //
  1673.     if (definite_try_stack -> Size() == 0)
  1674.         definite_block_stack -> ReturnSet(0) *= (*definitely_assigned_variables);
  1675.     else
  1676.     {
  1677.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1678.         {
  1679.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1680.             //
  1681.             // Is the return statement enclosed in a try main block or catch block
  1682.             // that  contains a finally clause. Note that a try statement is removed from
  1683.             // the definite_try_stack before its finally clause is processed. thus, a return
  1684.             // statement that is enclosed in a finally clause will appear in an enclosing
  1685.             // try statement, if any...
  1686.             //
  1687.             if (try_statement -> finally_clause_opt)
  1688.             {
  1689.                 int k;
  1690.                 for (k = definite_block_stack -> Size() - 1;
  1691.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1692.                      k--)
  1693.                     ;
  1694.  
  1695.                 assert(k >= 0);
  1696.  
  1697.                 definite_block_stack -> FinalReturnSet(k) += (*possibly_assigned_finals);
  1698.                 break;
  1699.             }
  1700.         }
  1701.     }
  1702.  
  1703.     //
  1704.     // After execution of a return statement, it is vacuously true
  1705.     // that every variable has definitely been assigned and no final
  1706.     // variable has been possibly assigned (as nothing is reachable
  1707.     // any way).
  1708.     //
  1709.     *definitely_assigned_variables = *universe;
  1710.     possibly_assigned_finals -> SetEmpty();
  1711.  
  1712.     return;
  1713. }
  1714.  
  1715.  
  1716. void Semantic::DefiniteThrowStatement(Ast *stmt)
  1717. {
  1718.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1719.  
  1720.     DefiniteAssignmentSet *after_expr = DefiniteExpression(throw_statement -> expression, *definitely_assigned_variables);
  1721.     if (after_expr)
  1722.         delete after_expr;
  1723.  
  1724.     //
  1725.     // Compute the set of variables that are definitely assigned prior to executing
  1726.     // this throw statement. Note that this set is only relevant to the method or
  1727.     // constructor block containing this statement.
  1728.     //
  1729.     // TODO: Do we really need this?
  1730.     //
  1731.     //    definite_block_stack -> TopThrowSet() *= (*definitely_assigned_variables);
  1732.     //
  1733.  
  1734.     //
  1735.     // Compute the set of variables that are possibly assigned prior to executing this throw statement
  1736.     // and update the proper enclosing block appropriately.
  1737.     //
  1738.     // We have a few cases to consider:
  1739.     //
  1740.     //    1. The throw statement is not contained in a try statement - the possibly-assigned
  1741.     //       set is only relevant to the enclosing method (or constructor) block. If the
  1742.     //       containing function in question is a method (i.e., not a constructor) then the
  1743.     //       definitely assigned set is updated as if the throw statement was a break statement
  1744.     //       out of the method block.
  1745.     //
  1746.     //    2. The throw statement is enclosed in a try statement main block or catch clause.
  1747.     //
  1748.     //        2a. if the nearest try-block that encloses the throw statement is a main try-block -
  1749.     //            the possibly-assigned block is relevant to that main block.
  1750.     //
  1751.     //        2b. if the nearest try-block that encloses the throw statement is a catch-block and
  1752.     //            the try block contains a finally clause - the possibly-assigned block is relevant
  1753.     //            to the catch-block
  1754.     //
  1755.     //        2c. otherwise, treat the throw statement as if it immediately followed its containing
  1756.     //            try statement
  1757.     //
  1758.     if (definite_try_stack -> Size() == 0)
  1759.     {
  1760.         if (ThisMethod() -> Identity() != control.init_name_symbol) // Not a constructor
  1761.             definite_block_stack -> ThrowSet(0) *= (*definitely_assigned_variables);
  1762.     }
  1763.     else
  1764.     {
  1765.         for (int i = definite_try_stack -> Size() - 1; i >= 0; i--)
  1766.         {
  1767.             AstTryStatement *try_statement = definite_try_stack -> TryStatement(i);
  1768.             //
  1769.             // Is the return statement enclosed in a try main block or catch block
  1770.             // that  contains a finally clause. Note that a try statement is removed from
  1771.             // the definite_try_stack before its finally clause is processed. thus, a return
  1772.             // statement that is enclosed in a finally clause will appear in an enclosing
  1773.             // try statement, if any...
  1774.             //
  1775.             if (try_statement -> block == definite_try_stack -> Block(i)) // Is the throw statement enclosed in main try block?
  1776.             {
  1777.                 int k;
  1778.                 for (k = definite_block_stack -> Size() - 1; definite_block_stack -> Block(k) != try_statement -> block; k--)
  1779.                     ;
  1780.  
  1781.                 assert(k >= 0);
  1782.  
  1783.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1784.                 break;
  1785.             }
  1786.             else if (try_statement -> finally_clause_opt)
  1787.             {
  1788.                 int k;
  1789.                 for (k = definite_block_stack -> Size() - 1;
  1790.                      definite_block_stack -> Block(k) != definite_try_stack -> Block(i);
  1791.                      k--)
  1792.                     ;
  1793.  
  1794.                 assert(k >= 0);
  1795.  
  1796.                 definite_block_stack -> FinalThrowSet(k) += (*possibly_assigned_finals);
  1797.                 break;
  1798.             }
  1799.         }
  1800.     }
  1801.  
  1802.     //
  1803.     // After execution of a throw statement, it is vacuously true
  1804.     // that every variable has definitely been assigned and no final
  1805.     // variable has been possibly assigned (as nothing is reachable
  1806.     // any way).
  1807.     //
  1808.     *definitely_assigned_variables = *universe;
  1809.     possibly_assigned_finals -> SetEmpty();
  1810.  
  1811.     return;
  1812. }
  1813.  
  1814.  
  1815. void Semantic::DefiniteTryStatement(Ast *stmt)
  1816. {
  1817.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1818.     definite_try_stack -> Push(try_statement);
  1819.  
  1820.     BitSet starting_set(*definitely_assigned_variables);
  1821.  
  1822.     AstBlock *try_block_body = try_statement -> block;
  1823.     definite_block_stack -> Push(try_block_body);
  1824.     definite_try_stack -> SetTopBlock(try_block_body);
  1825.  
  1826.     for (int j = 0; j < try_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1827.     {
  1828.         VariableSymbol *variable = try_block_body -> block_symbol -> VariableSym(j);
  1829.  
  1830.         possibly_assigned_finals -> RemoveElement(variable -> LocalVariableIndex());
  1831.         definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1832.         definite_visible_variables -> AddElement(variable);
  1833.     }
  1834.  
  1835.     BitSet before_try_finals(*possibly_assigned_finals);
  1836.  
  1837.     DefiniteBlockStatements(try_block_body);
  1838.  
  1839. #ifdef DUMP
  1840. if (control.option.g && try_block_body -> NumLocallyDefinedVariables() > 0)
  1841. {
  1842. Coutput << "(6) At Line " << lex_stream -> Line(try_block_body -> RightToken())
  1843.         << " the range for the following variables end:\n\n";
  1844. for (int k = 0; k < try_block_body -> NumLocallyDefinedVariables(); k++)
  1845. Coutput << "    \"" << try_block_body -> LocallyDefinedVariable(k) -> Name() << "\"\n";
  1846. }
  1847. #endif
  1848.     BitSet &exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals),
  1849.            before_catch_finals(exit_set),
  1850.            possibly_finals_union(exit_set);
  1851.  
  1852.     //
  1853.     // Once we are done with a block, its enclosed local variables are no longer visible.
  1854.     //
  1855.     for (int l = 0; l < try_block_body -> block_symbol -> NumVariableSymbols(); l++)
  1856.         definite_visible_variables -> RemoveElement(try_block_body -> block_symbol -> VariableSym(l));
  1857.  
  1858.     definite_block_stack -> Pop();
  1859.  
  1860.     //
  1861.     // We initilize the variable after_blocks here. It is used to calculate intersection
  1862.     // of the set of variables that are definitely assigned by all the blocks: the try block,
  1863.     // all the catch blocks, if any, and the finally block, if there is one.
  1864.     //
  1865.     BitSet after_blocks(*definitely_assigned_variables);
  1866.  
  1867.     //
  1868.     // Recall that the body of the catch blocks must not be
  1869.     // processed within the environment of the associated try whose
  1870.     // exceptions they are supposed to catch but within the immediate
  1871.     // enclosing block (which may itself be a try block).
  1872.     //
  1873.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1874.     {
  1875.         *definitely_assigned_variables = starting_set;
  1876.  
  1877.         //
  1878.         // We process the catch block here instead of invoking DefiniteBlock,
  1879.         // in order to make sure that the formal parameter (which is declared)
  1880.         // inside the block is identified as having been definitely assigned.
  1881.         //
  1882.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1883.  
  1884.         AstBlock *clause_block_body = clause -> block;
  1885.         definite_block_stack -> Push(clause_block_body);
  1886.         definite_try_stack -> SetTopBlock(clause_block_body);
  1887.  
  1888.         for (int j = 0; j < clause_block_body -> block_symbol -> NumVariableSymbols(); j++)
  1889.         {
  1890.             VariableSymbol *variable = clause_block_body -> block_symbol -> VariableSym(j);
  1891.  
  1892.             possibly_assigned_finals -> RemoveElement(variable -> LocalVariableIndex());
  1893.             definitely_assigned_variables -> RemoveElement(variable -> LocalVariableIndex());
  1894.             definite_visible_variables -> AddElement(variable);
  1895.         }
  1896.  
  1897.         //
  1898.         // The parameter must be (re) added after removing all variables in the block
  1899.         // from the set !!!
  1900.         //
  1901.         definitely_assigned_variables -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1902.         if (control.option.g)
  1903.         {
  1904.             VariableSymbol *variable = clause -> parameter_symbol;
  1905.             definite_block_stack -> TopLocallyDefinedVariables() -> AddElement(variable -> LocalVariableIndex());
  1906. #ifdef DUMP
  1907. Coutput << "(7) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  1908.         << "\" is defined at line " << lex_stream -> Line(clause -> formal_parameter -> LeftToken())
  1909.         << "\n";
  1910. #endif
  1911.         }
  1912.         *possibly_assigned_finals = before_catch_finals;
  1913.         if (clause -> parameter_symbol -> ACC_FINAL())
  1914.             possibly_assigned_finals -> AddElement(clause -> parameter_symbol -> LocalVariableIndex());
  1915.  
  1916.         DefiniteBlockStatements(clause_block_body);
  1917.  
  1918. #ifdef DUMP
  1919. if (control.option.g && clause_block_body -> NumLocallyDefinedVariables() > 0)
  1920. {
  1921. Coutput << "(8) At Line " << lex_stream -> Line(clause_block_body -> RightToken())
  1922.         << " the range for the following variables end:\n\n";
  1923. for (int l = 0; l < clause_block_body -> NumLocallyDefinedVariables(); l++)
  1924. Coutput << "    \"" << clause_block_body -> LocallyDefinedVariable(l) -> Name() << "\"\n";
  1925. }
  1926. #endif
  1927.         //
  1928.         // Once we are done with a block, its enclosed local variables are no longer visible.
  1929.         //
  1930.         for (int k = 0; k < clause_block_body -> block_symbol -> NumVariableSymbols(); k++)
  1931.             definite_visible_variables -> RemoveElement(clause_block_body -> block_symbol -> VariableSym(k));
  1932.  
  1933.         possibly_finals_union += definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  1934.  
  1935.         definite_block_stack -> Pop();
  1936.  
  1937.         //
  1938.         // Process the set of variables that were definitely assigned
  1939.         // after this catch block
  1940.         //
  1941.         after_blocks *= *definitely_assigned_variables;
  1942.     }
  1943.  
  1944.     *possibly_assigned_finals = possibly_finals_union;
  1945.     definite_try_stack -> Pop();
  1946.  
  1947.     //
  1948.     // Like the catch clauses, a finally block must not be processed
  1949.     // in the environment of its associated try block but in the
  1950.     // environment of its immediate enclosing block.
  1951.     //
  1952.     if (try_statement -> finally_clause_opt)
  1953.     {
  1954.         *definitely_assigned_variables = starting_set;
  1955.  
  1956.         DefiniteBlock(try_statement -> finally_clause_opt -> block);
  1957.  
  1958.         *definitely_assigned_variables += after_blocks;
  1959.     }
  1960.     else *definitely_assigned_variables = after_blocks;
  1961.  
  1962.     return;
  1963. }
  1964.  
  1965.  
  1966. void Semantic::DefiniteEmptyStatement(Ast *stmt)
  1967. {
  1968.     return;
  1969. }
  1970.  
  1971.  
  1972. void Semantic::DefiniteClassDeclaration(Ast *decl)
  1973. {
  1974.     //
  1975.     // All the methods within the body of a local class are processed when
  1976.     // the class is compiled.
  1977.     //
  1978.  
  1979.     return;
  1980. }
  1981.  
  1982.  
  1983. void Semantic::DefiniteMethodBody(AstMethodDeclaration *method_declaration, Tuple<VariableSymbol *> &finals)
  1984. {
  1985.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1986.     {
  1987. #ifdef DUMP
  1988. if (control.option.g)
  1989. Coutput << "(9) Processing method \"" << method_declaration -> method_symbol -> Name()
  1990.         << "\" in " << ThisType() -> ContainingPackage() -> PackageName() << "/"
  1991.         << ThisType() -> ExternalName() << "\n";
  1992. #endif
  1993.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1994.         AstBlock *block_body = (constructor_block ? constructor_block -> block : (AstBlock *) method_declaration -> method_body);
  1995.  
  1996.         universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  1997.         definite_block_stack = new DefiniteBlockStack(control,
  1998.                                                       method_declaration -> method_symbol -> max_block_depth,
  1999.                                                       universe -> Size());
  2000.         definite_try_stack = new DefiniteTryStack(method_declaration -> method_symbol -> max_block_depth);
  2001.         definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  2002.         definite_visible_variables = new SymbolSet(universe -> Size());
  2003.         definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  2004.         possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  2005.         for (int i = 0; i < finals.Length(); i++) // Assume that all final instance variables have been assigned a value.
  2006.         {
  2007.             int index = block_body -> block_symbol -> max_variable_index + i;
  2008.             finals[i] -> SetLocalVariableIndex(index);
  2009.             definitely_assigned_variables -> AddElement(index);
  2010.             possibly_assigned_finals -> AddElement(index);
  2011.             definite_visible_variables -> AddElement(finals[i]);
  2012.         }
  2013.  
  2014.         definite_block_stack -> Push(block_body);
  2015.  
  2016.         AstMethodDeclarator *method_declarator = method_declaration -> method_declarator;
  2017.         for (int k = 0; k < method_declarator -> NumFormalParameters(); k++)
  2018.         {
  2019.             AstVariableDeclarator *formal_declarator = method_declarator -> FormalParameter(k) -> formal_declarator;
  2020.             definitely_assigned_variables -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  2021.             if (control.option.g)
  2022.             {
  2023.                 VariableSymbol *variable = formal_declarator -> symbol;
  2024.                 definite_block_stack -> TopLocallyDefinedVariables() -> AddElement(variable -> LocalVariableIndex());
  2025. #ifdef DUMP
  2026. Coutput << "(10) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  2027.         << "\" is defined at line " << lex_stream -> Line(formal_declarator -> LeftToken())
  2028.         << "\n";
  2029. #endif
  2030.             }
  2031.  
  2032.             if (formal_declarator -> symbol -> ACC_FINAL())
  2033.                 possibly_assigned_finals -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  2034.             definite_visible_variables -> AddElement(formal_declarator -> symbol);
  2035.         }
  2036.  
  2037.         for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  2038.         {
  2039.             VariableSymbol *variable = block_body -> block_symbol -> VariableSym(l);
  2040.             definite_visible_variables -> AddElement(variable);
  2041.         }
  2042.  
  2043.         DefiniteBlockStatements(block_body);
  2044.  
  2045. #ifdef DUMP
  2046. if (control.option.g && block_body -> NumLocallyDefinedVariables() > 0)
  2047. {
  2048. Coutput << "(11) At Line " << lex_stream -> Line(block_body -> RightToken())
  2049.         << " the range for the following variables end:\n\n";
  2050. for (int j = 0; j < block_body -> NumLocallyDefinedVariables(); j++)
  2051. Coutput << "    \"" << block_body -> LocallyDefinedVariable(j) -> Name() << "\"\n";
  2052. }
  2053. #endif
  2054.         definite_block_stack -> Pop();
  2055.  
  2056.         delete universe;
  2057.         delete definitely_assigned_variables;
  2058.         delete definite_block_stack;
  2059.         delete definite_try_stack;
  2060.         delete definite_final_assignment_stack;
  2061.         delete definite_visible_variables;
  2062.         delete possibly_assigned_finals;
  2063.     }
  2064.  
  2065.     return;
  2066. }
  2067.  
  2068.  
  2069. void Semantic::DefiniteConstructorBody(AstConstructorDeclaration *constructor_declaration, Tuple<VariableSymbol *> &finals)
  2070. {
  2071. #ifdef DUMP
  2072. if (control.option.g)
  2073. Coutput << "(12) Processing constructor \"" << constructor_declaration -> constructor_symbol -> Name()
  2074.         << "\" in " << ThisType() -> ContainingPackage() -> PackageName() << "/"
  2075.         << ThisType() -> ExternalName() << "\n";
  2076. #endif
  2077.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  2078.     AstBlock *block_body = constructor_block -> block;
  2079.  
  2080.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  2081.     definite_block_stack = new DefiniteBlockStack(control,
  2082.                                                   constructor_declaration -> constructor_symbol -> max_block_depth,
  2083.                                                   universe -> Size());
  2084.     definite_try_stack = new DefiniteTryStack(constructor_declaration -> constructor_symbol -> max_block_depth);
  2085.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  2086.     definite_visible_variables = new SymbolSet(universe -> Size());
  2087.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  2088.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  2089.     for (int i = 0; i < finals.Length(); i++)
  2090.     {
  2091.         int index = block_body -> block_symbol -> max_variable_index + i;
  2092.  
  2093.         finals[i] -> SetLocalVariableIndex(index);
  2094.         if (finals[i] -> IsDefinitelyAssigned())
  2095.         {
  2096.             definitely_assigned_variables -> AddElement(index);
  2097.             possibly_assigned_finals -> AddElement(index);
  2098.         }
  2099.         else if (finals[i] -> IsPossiblyAssigned())
  2100.             possibly_assigned_finals -> AddElement(index);
  2101.         definite_visible_variables -> AddElement(finals[i]);
  2102.     }
  2103.  
  2104.     //
  2105.     // As an explicit constructor call cannot refer to any locally declared variables
  2106.     // other than formal parameters, no local variable can be assigned within it (other
  2107.     // than a formal parameter which is considered to have been assigned anyway). Therefore,
  2108.     // the following code is not necessary:
  2109.     //
  2110.     //    if (this_call)
  2111.     //         DefiniteThisCall(this_call);
  2112.     //    else if (super_call)
  2113.     //         DefiniteSuperCall(super_call);
  2114.     //
  2115.  
  2116.     definite_block_stack -> Push(block_body);
  2117.     if (control.option.g)
  2118.     {
  2119.         //
  2120.         // We need this initialization to prevent debug info from being generated for 
  2121.         // final fields (since they are not truly local variables).
  2122.         //
  2123.         BitSet &locally_defined_variables = *definite_block_stack -> TopLocallyDefinedVariables();
  2124.         for (int i = 0; i < finals.Length(); i++) // Assume that all final instance variables have been assigned a value.
  2125.         {
  2126.             int index = block_body -> block_symbol -> max_variable_index + i;
  2127.             locally_defined_variables.AddElement(index);
  2128.         }
  2129.     }
  2130.  
  2131.     AstMethodDeclarator *constructor_declarator = constructor_declaration -> constructor_declarator;
  2132.     for (int j = 0; j < constructor_declarator -> NumFormalParameters(); j++)
  2133.     {
  2134.         AstVariableDeclarator *formal_declarator = constructor_declarator -> FormalParameter(j) -> formal_declarator;
  2135.         definitely_assigned_variables -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  2136.         if (control.option.g)
  2137.         {
  2138.             VariableSymbol *variable = formal_declarator -> symbol;
  2139.             definite_block_stack -> TopLocallyDefinedVariables() -> AddElement(variable -> LocalVariableIndex());
  2140. #ifdef DUMP
  2141. Coutput << "(13) Variable \"" << variable -> Name() << " #" << variable -> LocalVariableIndex()
  2142.         << "\" is defined at line " << lex_stream -> Line(formal_declarator -> LeftToken())
  2143.         << "\n";
  2144. #endif
  2145.         }
  2146.  
  2147.         if (formal_declarator -> symbol -> ACC_FINAL())
  2148.             possibly_assigned_finals -> AddElement(formal_declarator -> symbol -> LocalVariableIndex());
  2149.         definite_visible_variables -> AddElement(formal_declarator -> symbol);
  2150.     }
  2151.  
  2152.     for (int l = 0; l < block_body -> block_symbol -> NumVariableSymbols(); l++)
  2153.     {
  2154.         VariableSymbol *variable = block_body -> block_symbol -> VariableSym(l);
  2155.         definite_visible_variables -> AddElement(variable);
  2156.     }
  2157.  
  2158.     DefiniteBlockStatements(block_body);
  2159.  
  2160. #ifdef DUMP
  2161. if (control.option.g && block_body -> NumLocallyDefinedVariables() > 0)
  2162. {
  2163. Coutput << "(14) At Line " << lex_stream -> Line(block_body -> RightToken())
  2164.         << " the range for the following variables end:\n\n";
  2165. for (int j = 0; j < block_body -> NumLocallyDefinedVariables(); j++)
  2166. Coutput << "    \"" << block_body -> LocallyDefinedVariable(j) -> Name() << "\"\n";
  2167. }
  2168. #endif
  2169.     //
  2170.     // Compute the set of finals that has definitely been assigned in this constructor
  2171.     //
  2172.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  2173.     for (int k = 0; k < finals.Length(); k++)
  2174.     {
  2175.         int index = block_body -> block_symbol -> max_variable_index + k;
  2176.         if (exit_set[index])
  2177.             finals[k] -> MarkDefinitelyAssigned();
  2178.     }
  2179.  
  2180.     definite_block_stack -> Pop();
  2181.  
  2182.     delete universe;
  2183.     delete definitely_assigned_variables;
  2184.     delete definite_block_stack;
  2185.     delete definite_try_stack;
  2186.     delete definite_final_assignment_stack;
  2187.     delete definite_visible_variables;
  2188.     delete possibly_assigned_finals;
  2189.  
  2190.     return;
  2191. }
  2192.  
  2193.  
  2194. void Semantic::DefiniteBlockInitializer(AstBlock *block_body, int stack_size, Tuple<VariableSymbol *> &finals)
  2195. {
  2196. #ifdef DUMP
  2197. if (control.option.g)
  2198. Coutput << "(15) Processing Initializer block "
  2199.         << " in " << ThisType() -> ContainingPackage() -> PackageName() << "/"
  2200.         << ThisType() -> ExternalName() << "\n";
  2201. #endif
  2202.     universe = new BitSet(block_body -> block_symbol -> max_variable_index + finals.Length(), BitSet::UNIVERSE);
  2203.     definite_block_stack = new DefiniteBlockStack(control, stack_size + 1, universe -> Size()); // +1 for absent method block
  2204.     definite_try_stack = new DefiniteTryStack(stack_size + 1);
  2205.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  2206.     definite_visible_variables = new SymbolSet(universe -> Size());
  2207.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  2208.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  2209.     for (int i = 0; i < finals.Length(); i++)
  2210.     {
  2211.         int index = block_body -> block_symbol -> max_variable_index + i;
  2212.  
  2213.         finals[i] -> SetLocalVariableIndex(index);
  2214.         if (finals[i] -> IsDefinitelyAssigned())
  2215.         {
  2216.             definitely_assigned_variables -> AddElement(index);
  2217.             possibly_assigned_finals -> AddElement(index);
  2218.         }
  2219.         else if (finals[i] -> IsPossiblyAssigned())
  2220.             possibly_assigned_finals -> AddElement(index);
  2221.         definite_visible_variables -> AddElement(finals[i]);
  2222.     }
  2223.  
  2224.     definite_block_stack -> Push(NULL); // No method available
  2225.     definite_block_stack -> Push(block_body);
  2226.     if (control.option.g)
  2227.     {
  2228.         //
  2229.         // We need this initialization to prevent debug info from being generated for 
  2230.         // final fields (since they are not truly local variables).
  2231.         //
  2232.         BitSet &locally_defined_variables = *definite_block_stack -> TopLocallyDefinedVariables();
  2233.         for (int i = 0; i < finals.Length(); i++) // Assume that all final instance variables have been assigned a value.
  2234.         {
  2235.             int index = block_body -> block_symbol -> max_variable_index + i;
  2236.             locally_defined_variables.AddElement(index);
  2237.         }
  2238.     }
  2239.  
  2240.     for (int j = 0; j < block_body -> block_symbol -> NumVariableSymbols(); j++)
  2241.     {
  2242.         VariableSymbol *variable = block_body -> block_symbol -> VariableSym(j);
  2243.         definite_visible_variables -> AddElement(variable);
  2244.     }
  2245.  
  2246.     DefiniteBlockStatements(block_body);
  2247.  
  2248. #ifdef DUMP
  2249. if (control.option.g && block_body -> NumLocallyDefinedVariables() > 0)
  2250. {
  2251. Coutput << "(16) At Line " << lex_stream -> Line(block_body -> RightToken())
  2252.         << " the range for the following variables end:\n\n";
  2253. for (int j = 0; j < block_body -> NumLocallyDefinedVariables(); j++)
  2254. Coutput << "    \"" << block_body -> LocallyDefinedVariable(j) -> Name() << "\"\n";
  2255. }
  2256. #endif
  2257.     //
  2258.     // For each final that has definitely been assigned a value in this block,
  2259.     // mark it appropriately.
  2260.     //
  2261.     BitSet &exit_set = definite_block_stack -> TopExitSet(*definitely_assigned_variables);
  2262.     for (int k = 0; k < finals.Length(); k++)
  2263.     {
  2264.         int index = block_body -> block_symbol -> max_variable_index + k;
  2265.         if (exit_set[index])
  2266.             finals[k] -> MarkDefinitelyAssigned();
  2267.     }
  2268.  
  2269.     //
  2270.     // For each final that may have possibly been assigned a value in this block,
  2271.     // mark it appropriately.
  2272.     //
  2273.     exit_set = definite_block_stack -> TopFinalExitSet(*possibly_assigned_finals);
  2274.     for (int l = 0; l < finals.Length(); l++)
  2275.     {
  2276.         int index = block_body -> block_symbol -> max_variable_index + l;
  2277.         if (exit_set[index])
  2278.             finals[l] -> MarkPossiblyAssigned();
  2279.     }
  2280.  
  2281.     definite_block_stack -> Pop();
  2282.     definite_block_stack -> Pop(); // remove NULL that was pushed to indicate that no method is available
  2283.  
  2284.     delete universe;
  2285.     delete definitely_assigned_variables;
  2286.     delete definite_block_stack;
  2287.     delete definite_try_stack;
  2288.     delete definite_final_assignment_stack;
  2289.     delete definite_visible_variables;
  2290.     delete possibly_assigned_finals;
  2291.  
  2292.     return;
  2293. }
  2294.  
  2295.  
  2296. void Semantic::DefiniteVariableInitializer(AstVariableDeclarator *variable_declarator, Tuple<VariableSymbol *> &finals)
  2297. {
  2298.     universe = new BitSet(finals.Length(), BitSet::UNIVERSE);
  2299.     definite_block_stack = NULL;
  2300.     definite_try_stack = NULL;
  2301.     definite_final_assignment_stack =  new DefiniteFinalAssignmentStack();
  2302.     definite_visible_variables = new SymbolSet(universe -> Size());
  2303.     definitely_assigned_variables = new BitSet(universe -> Size(), BitSet::EMPTY);
  2304.     possibly_assigned_finals = new BitSet(universe -> Size(), BitSet::EMPTY);
  2305.     for (int i = 0; i < finals.Length(); i++)
  2306.     {
  2307.         finals[i] -> SetLocalVariableIndex(i);
  2308.         if (finals[i] -> IsDefinitelyAssigned())
  2309.         {
  2310.             definitely_assigned_variables -> AddElement(i);
  2311.             possibly_assigned_finals -> AddElement(i);
  2312.         }
  2313.         else if (finals[i] -> IsPossiblyAssigned())
  2314.             possibly_assigned_finals -> AddElement(i);
  2315.         definite_visible_variables -> AddElement(finals[i]);
  2316.     }
  2317.  
  2318.     DefiniteVariableInitializer(variable_declarator);
  2319.     VariableSymbol *symbol = variable_declarator -> symbol;
  2320.     if (symbol -> ACC_FINAL())
  2321.         symbol -> MarkDefinitelyAssigned();
  2322.     //
  2323.     // Also, update any other finals that may have been initialized as
  2324.     // a side-effect in an assignment embedded within the initializer
  2325.     // expression.
  2326.     //
  2327.     BitSet &exit_set = *definitely_assigned_variables;
  2328.     for (int k = 0; k < finals.Length(); k++)
  2329.     {
  2330.         if (exit_set[k])
  2331.             finals[k] -> MarkDefinitelyAssigned();
  2332.     }
  2333.  
  2334.     delete universe;
  2335.     delete definitely_assigned_variables;
  2336.     delete definite_final_assignment_stack;
  2337.     delete definite_visible_variables;
  2338.     delete possibly_assigned_finals;
  2339.  
  2340.     return;
  2341. }
  2342.